Cloud DNSの一般公開ゾーンのDNSクエリログを観察してみた

Cloud DNSの一般公開ゾーンのDNSクエリログを観察してみた

Clock Icon2024.11.06

概要

Cloud DNSにはCloud MonitoringとCloud Loggingを利用して、DNSゾーンとDNSクエリのパフォーマンスやステータスを監視できます。これにより、DNSの動作状況をリアルタイムで把握し、問題が発生した場合に迅速に対応できます。

というようなリファレンスの説明を読んでどんなもんじゃいと気になったので実際にCloud DNSの一般公開ゾーンのLoggingを有効にしてDNSクエリのログを観察してみました。

この記事の対象者

  • Cloud DNSでLoggingを有効にした場合にDNSクエリがどんな感じで出力されるのかざっくり知りたい人

やってみる

今回は一般公開のマネージドゾーンのLoggingをオンにして以下の条件で観察してみました。

  • Cloud Shellからdig
  • ローカルPC(Google Cloud NW外)からdig
  • default VPC内のGCEインスタンスからdig

※一般公開のマネージドゾーンを作成してあることを前提にしています。作成したことがないよ、という方は以下のブログも併せてご確認ください。
お名前.comで取得したドメインをCloud DNSで管理できるようにする

それではやってみます。

準備:一般公開のマネージドゾーンでのLogging

まずは以下のコマンドでLoggingをオンにします。ゾーン作成時にLoggingをオンにしていれば不要です。

gcloud dns --project=プロジェクトID managed-zones update ゾーン名 --log-dns-queries

Updating managed zone [ゾーン名]...done. と出力されたらオンになっています。

Cloud Shellからdig

まずはCloud Shellからdigしてみます。

dig ドメイン名

するとCloud Loggingにログが書き込まれているはずです。
ログエクスプローラで以下でログを検索します。

resource.type="dns_query"

スクリーンショット 2024-11-06 2.23.53

上記のようにログが出力されていたのでみてみます。

{
  "insertId": "1xzjheyepcs53",
  "jsonPayload": {
    "serverLatency": 0,
    "structuredRdata": [
      {
        "rvalue": "**.**.**.**",
        "type": "A",
        "ttl": "300",
        "class": "IN",
        "domainName": "ドメイン名."
      }
    ],
    "sourceIP": "送信元IP",
    "protocol": "UDP",
    "responseCode": "NOERROR",
    "queryType": "A",
    "queryName": "ドメイン名.",
    "authAnswer": true,
    "dns64Translated": false,
    "destinationIP": "216.239.36.*"
  },
  "resource": {
    "type": "dns_query",
    "labels": {
      "target_name": "ゾーン名",
      "project_id": "プロジェクトID",
      "target_type": "public-zone",
      "source_type": "internet",
      "location": "global"
    }
  },
  "timestamp": "2024-11-05T16:09:59.042643071Z",
  "severity": "INFO",
  "logName": "projects/プロジェクトID/logs/dns.googleapis.com%2Fdns_queries",
  "receiveTimestamp": "2024-11-05T16:09:59.528230991Z"
}

意味をざっくりと翻訳すると以下となります。

フィールド 説明
insertId ログエントリの一意の識別子。このIDはログエントリが重複しないようにするために使用されます。
jsonPayload ログの内容を表すJSONオブジェクト。DNSクエリに関する詳細な情報が含まれています。
jsonPayload.serverLatency DNSサーバーの応答時間(ミリ秒)。今回の例では0ミリ秒。
jsonPayload.structuredRdata 応答データの詳細を含む配列。
jsonPayload.structuredRdata[].rvalue レコードの値(IPアドレス)。
jsonPayload.structuredRdata[].type DNSレコードのタイプ。この例では「Aレコード」。
jsonPayload.structuredRdata[].ttl レコードの有効期間(Time To Live)。この例では「300秒」。
jsonPayload.structuredRdata[].class DNSクラス。通常は「IN」(インターネット)。
jsonPayload.structuredRdata[].domainName クエリされたドメイン名。マスクしています。
jsonPayload.sourceIP クエリを送信したクライアントのIPアドレス。
jsonPayload.protocol 使用されたプロトコル。この例では「UDP」。
jsonPayload.responseCode DNS応答のステータスコード。「NOERROR」はエラーなしを示す。
jsonPayload.queryType クエリのタイプ。この例では「Aレコード」。
jsonPayload.queryName クエリされたドメイン名。マスクしています。
jsonPayload.authAnswer 権威あるDNSサーバーからの応答かどうか。この例では「true」。
jsonPayload.dns64Translated DNS64変換が行われたかどうか。この例では「false」。
jsonPayload.destinationIP クエリが送信されたDNSサーバーのIPアドレス。この例では「216.239.36.*」。これはGoogle CloudのIPです。
resource ログエントリに関連するリソース情報。
resource.type リソースのタイプ。この例では「dns_query」。
resource.labels リソースに関連するラベル情報。
resource.labels.target_name クエリ対象のゾーン名。マスクしています。
resource.labels.project_id プロジェクトのID。マスクしています。
resource.labels.target_type クエリ対象のゾーンタイプ。この例では「public-zone」(パブリックゾーン)。
resource.labels.source_type クエリの送信元タイプ。この例では「internet」(インターネット)。
resource.labels.location リソースの場所。この例では「global」(グローバル)。
timestamp ログエントリのタイムスタンプ。この例では「2024-11-05T16:09:59.042643071Z」。
severity ログの重大度レベル。この例では「INFO」。
logName ログの名前とパス。マスクしています。
receiveTimestamp ログが受信されたタイムスタンプ。。

いろいろなフィールドが出ていますね。
jsonPayload.structuredRdata[].typeAと出ていたり(digと一致)、
jsonPayload.destinationIP216.239.36.*→公開されているGoogle CloudのIPに合致。
https://support.google.com/a/answer/10026322?hl=ja

他にもいろいろな情報が出ていますがとりあえずDNSクエリログをLoggingで見ることができました。

ローカルPC(Google Cloud NW外)からdig

ローカルPCからもdigしてみました。
ほぼ同じだったので差分だけ以下にまとました。

フィールド 最初のログ 最新のログ 差分
insertId "1xzjheyepcs53" "152xrd3e5cwkp" IDが異なる
jsonPayload.sourceIP "..." "..." クエリを送信したIPアドレスが異なる。
jsonPayload.destinationIP "216.239.36.*" "216.239.34.*" IPアドレスが異なる
timestamp "2024-11-05T16:09:59.042643071Z" "2024-11-05T16:31:27.300364098Z" タイムスタンプが異なる
receiveTimestamp "2024-11-05T16:09:59.528230991Z" "2024-11-05T16:31:28.735056393Z" 受信タイムスタンプが異なる

sourceIPは自分のPCのIPでした。またdestinationIPが異なっていることが確認できました。Google Cloud DNSは、複数のDNSサーバーを使用して高可用性と負荷分散を実現しているので異なるdestinationIPは、異なるDNSサーバーにクエリが送信されたからと考えられます。

default VPC内のGCEインスタンスからdig

ほぼ同じだったので今度はGCEインスタンスからTXTレコードをクエリしてみます。

dig ドメイン名 TXT
{
  "insertId": "1jteezwe1hgek",
  "jsonPayload": {
    "queryName": "ドメイン名.",
    "dns64Translated": false,
    "structuredRdata": [
      {
        "ttl": "60",
        "type": "TXT",
        "domainName": "ドメイン名.",
        "class": "IN",
        "rvalue": "\\# 19 1248656c6c6f20436c6f756420444e53212121"
      }
    ],
    "sourceIP": "送信元IP",
    "destinationIP": "216.239.32.110",
    "protocol": "UDP",
    "queryType": "TXT",
    "authAnswer": true,
    "serverLatency": 0,
    "responseCode": "NOERROR"
  },
  "resource": {
    "type": "dns_query",
    "labels": {
      "project_id": "プロジェクトID",
      "target_name": "ゾーン名",
      "target_type": "public-zone",
      "location": "global",
      "source_type": "internet"
    }
  },
  "timestamp": "2024-11-05T16:44:48.675909291Z",
  "severity": "INFO",
  "logName": "projects/プロジェクトID/logs/dns.googleapis.com%2Fdns_queries",
  "receiveTimestamp": "2024-11-05T16:44:49.832018041Z"
}

面白そうなところをピックします。

フィールド 説明
type クエリのタイプ。この例では「TXT」。
rvalue \\# 19 1248656c6c6f20436c6f756420444e53212121はバイナリ形式のデータです。\\#はバイナリ形式のデータが続くことを示します。19はデータのバイト数(16進数)ですので10進数だと25バイトとなります。

TXTレコードをクエリした場合は当然ながらDNSクエリのタイプがTXTになることが確認できました。

おまけ:rvalueを解読してみる。

rvalueの16進数データ1248656c6c6f20436c6f756420444e53212121をASCII文字に変換してみます。

16進数 10進数 ASCII文字
12 18 (制御文字)
48 72 H
65 101 e
6c 108 l
6c 108 l
6f 111 o
20 32 (スペース)
43 67 C
6c 108 l
6f 111 o
75 117 u
64 100 d
20 32 (スペース)
44 68 D
4e 78 N
53 83 S
21 33 !
21 33 !
21 33 !

上記よりHello Cloud DNS!!!という文字列と判明しました。
ちなみにこの値は私がTXTレコードに設定している値なので、みなさんの環境ではまた違った値になりますのでご注意ください。

ログの観察が終わって満足しましたら以下のコマンドを打ってLoggingをオフにしておきます。

gcloud dns managed-zones update ゾーン名 --no-log-dns-queries

まとめ

今回3つのパターンを試してみましたがレコードタイプを除けば特にログに違いはありませんでした。とはいえDNSクエリログでどういった様子で出力されるかが実際に見れたのでとても良い検証でした。
限定公開ゾーンに対してのDNSクエリログは今回は試せていないので今度試してみます。

それではまた。ナマステー

参考

https://cloud.google.com/dns/docs/monitoring?hl=ja

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.